<?php
/**
 * @file
 */

/**
 * Get chatroom
 */
function chatroom_livesupport_render_chatroom($chatroom = ChatroomLivesupport, $attributes = array()) {
  if ($chatroom->get('cid')) {
    global $user;
    $name = $user->uid ? $user->name : variable_get('anonymous', t('Anonymous'));
    nodejs_send_content_channel_token('chatroom_' . $chatroom->get('cid'), TRUE);
    $user_online_message = (object) array(
      'channel' => 'chatroom_' . $chatroom->get('cid'),
      'callback' => 'chatroomUserOnlineHandler',
      'data' => array(
        'cid' => $chatroom->get('cid'),
        'uid' => $user->uid,
        'name' => $name,
      ),
    );
    nodejs_send_content_channel_message($user_online_message);
    return theme('chatroom_livesupport', array('chatroom' => $chatroom, 'attributes' => $attributes));
  }
  return t('Chatroom is not available');
}

/**
 * Create chatroom livesupport
 */
function chatroom_livesupport_create_chatroom($account = NULL) {
  global $user;
  if ($account == NULL) {
    $account = $user;
  }
  $account->read_only = 0;
  $account->modified = REQUEST_TIME;
  $chatroom = new ChatroomLivesupport();
  $chatroom->set('title', t('Support for @user', array('@user' => $account->name)));
  $chatroom->set('public', 0);
  $chatroom->set('uid', $account->uid);
  $chatroom->set('format', variable_get('chatroom_livesupport_msg_format', 'plain_text'));
  $chatroom->set('status', 0);
  $chatroom->set('modified', REQUEST_TIME);
  $chatroom->set('allowedUids', array($account));
  $chatroom->save();
  return $chatroom;
}

/**
 * Reopen exists chatroom livesupport
 */
function chatroom_livesupport_reopen_chatroom($cid = NULL) {
  global $user;
  $user->read_only = 0;
  $user->modified = REQUEST_TIME;
  $chatroom = new ChatroomLivesupport($cid);
  $allowedUids = $chatroom->get('allowedUids');
  $allowedUids[] = $user;
  $chatroom->set('allowedUids', $allowedUids);
  $chatroom->set('status', CHATROOM_IN_QUEUE);  
  $chatroom->save();
  return $chatroom;
}

/**
 * Save messages.
 */
function chatroom_livesupport_get_default_message($chatroom, $account) {
  // Load default message
  $message = array(
    'cid' => $chatroom->get('cid'),
    'uid' => $account->uid,
    'msg' => t('I\'m busy'),
    'sid' => session_id(),
    'msg_type' => 'message',
    'recipient_uid' => 0,
    'modified' => time(),
    'anon_name' => '',
  );
  return $message;
}

/**
 * Get chatroom latest operators
 */
function chatroom_livesupport_get_latest_operator($cid) {
  $operators = db_select("chatroom_user", 'cu');
  $operators->leftJoin('users', 'u', 'u.uid = cu.uid');
  $operators->fields('cu', array('cid', 'modified'));
  $operators->fields('u');
  $operators->condition('cid', $cid);
  $operators->orderBy('modified', 'DESC');
  $operators->range(0,1);
  $operators = $operators->execute();

  return $operators->fetchAssoc();
}

/**
 * Get chatroom for user is visitor
 */
function chatroom_livesupport_get_chatroom_from_user($uid) {
  $query = db_select("chatroom", 'c');
  $query->fields('c');
  $query->condition('uid', $uid);
  $chatroom = $query->execute()->fetchAssoc();

  if ($chatroom) {
    $chatroom = new ChatroomLivesupport($chatroom['cid']);
    return $chatroom;
  }
  return FALSE;
}


/**
 * Get operators online
 */
function chatroom_livesupport_get_online_operators() {
  $interval = REQUEST_TIME - variable_get('user_block_seconds_online', 900);
  $operators = db_select("chatroom_operator", 'o');
  $operators->leftJoin('users', 'u', 'u.uid = o.uid');
  $operators->leftJoin('sessions', 's', 'u.uid = s.uid');
  $operators->fields('o', array('oid', 'timestamp'));
  $operators->fields('u');
  $operators->condition('s.timestamp', $interval, '>=');
  $operators = $operators->execute();

  return $operators->fetchAll();
}

/**
 * Get all operators
 */
function chatroom_livesupport_get_operators() {
  $operators = db_select("chatroom_operator", 'o');
  $operators->leftJoin('users', 'u', 'u.uid = o.uid');
  $operators->fields('o', array('oid', 'timestamp'));
  $operators->fields('u');
  $operators = $operators->execute();
  return $operators->fetchAll();
}

/**
 * Get all visitor
 */
function chatroom_livesupport_get_visitors ($filter = array(), $limit = 0) {
  $query = db_select('chatroom', 'c');
  $query->innerJoin('users', 'u', 'u.uid = c.uid');
  $query->leftJoin('chatroom_user', 'cu', 'cu.uid = c.uid AND cu.cid = c.cid');
  $query->fields('c', array('cid', 'title', 'status', 'modified'));
  $query->fields('u', array('uid', 'name'));
  $query->addField('cu', 'modified', 'joined');
  $query->addExpression("(SELECT cu2.uid FROM {chatroom_user} cu2
    INNER JOIN {chatroom_operator} co ON cu2.uid = co.uid
    WHERE c.cid = cu2.cid ORDER BY modified DESC LIMIT 1)", 'operator');

  $query->condition('u.uid', 0, '<>');

  if (!empty($filter['name'])) {
    $query->condition('u.name', $filter['name'], 'LIKE');
  }
  if (!empty($filter['status'])) {
    $query->condition('c.status', $filter['status'], 'IN');
  }
  if ($limit) {
    $query->range(0, $limit);
  }
  $result = $query->execute();
  return $result;
}

/**
 * Check operator online
 */
function chatroom_livesupport_is_online_user($uid = 0) {
  $interval = REQUEST_TIME - variable_get('user_block_seconds_online', 900);
  $is_online = db_query('SELECT uid FROM {sessions} s WHERE s.timestamp >= :interval AND s.uid = :uid', array(':interval' => $interval, ':uid' => $uid))->rowCount();
  return $is_online;
}

/**
 * Check user is operator
 */
function chatroom_livesupport_user_is_operator($uid = 0) {
  global $user;
  if ($uid == 0) {
    $uid = $user->uid;
  }
  $is_operator = db_select('chatroom_operator', 'o')
    ->fields('o')
    ->condition('uid', $uid)
    ->execute()
    ->rowCount();
  return $is_operator ? TRUE : FALSE;
}

/**
 * Save new operator
 */
function chatroom_livesupport_save_operator($operator) {
  $operator = (object) $operator;
  $operator->timestamp = REQUEST_TIME;
  $count = db_select('chatroom_operator', 'o')
    ->fields('o')
    ->condition('uid', $operator->uid)
    ->execute()
    ->rowCount();
  if (!$count) {
    drupal_write_record('chatroom_operator', $operator);
  }
  return $operator;
}

/**
 * Chatroom state options
 */

function chatroom_livesupport_chatroom_states($state = '') {
  $states = array(
    0 => t('Waiting for operator'),
    1 => t('In Queue'),
    2 => t('In Chat'),
    3 => t('Closed'),
  );
  if ($state != '') {
    return isset($states[$state]) ? $states[$state] : '';
  }
  return $states;
}

/**
 * Helper send mail
 */
function _chatroom_livesupport_mail_notify($op, $chatroom = ChatroomLivesupport, $account, $language = NULL) {
  $notify = variable_get('chatroom_livesupport_' . $op, FALSE);
  if ($notify) {
    $query = db_select("chatroom", 'c');
    $query->fields('c');
    $query->condition('cid', $chatroom->get('cid'));
    $chatroom = $query->execute()->fetchAssoc();
    $params['chatroom'] = (object)$chatroom;
    if (chatroom_livesupport_user_is_operator($account->uid)) {
      $params['operator'] = (object)$account;
    }
    $language = $language ? $language : language_default();
    $mail = drupal_mail('chatroom_livesupport', $op, $account->mail, $language, $params);

  }
  return empty($mail) ? NULL : $mail['result'];
}

/**
 * Returns a mail string for a variable name.
 *
 * Used by chatroom_livesupport_mail() and the settings forms to retrieve strings.
 */
function _chatroom_livesupport_mail_text($key, $language = NULL, $variables = array(), $replace = TRUE) {
  $langcode = isset($language) ? $language->language : NULL;

  if ($admin_setting = variable_get('chatroom_livesupport_email_' . $key, FALSE)) {
    // An admin setting overrides the default string.
    $text = $admin_setting;
  }
  else {
    // No override, return default string.
    switch ($key) {
      case 'notify_operator_subject':
        $text = t('Visitor [chatroom-user:name] has been required support at [chatroom:modified]', array(), array('langcode' => $langcode));
        break;
      case 'notify_operator_body':
        $text = t('[user:name], Visitor [chatroom-user:name] has been required support at [chatroom:modified]', array(), array('langcode' => $langcode));
        break;
      case 'notify_visitor_subject':
        $text = t('Operator [chatroom-operator:name] has been joined chatroom', array(), array('langcode' => $langcode));
        break;
      case 'notify_visitor_body':
        $text = t('[chatroom-user:name], Operator [chatroom-operator:name] has been joined chatroom at [chatroom-operator:modified]', array(), array('langcode' => $langcode));
        break;
    }
  }

  if ($replace) {
    // We do not sanitize the token replacement, since the output of this
    // replacement is intended for an e-mail message, not a web browser.
    return token_replace($text, $variables, array('language' => $language, 'callback' => '', 'sanitize' => FALSE, 'clear' => TRUE));
  }

  return $text;
}

/**
 * Realtime via nodejs callback handler
 */

/**
 * Function helper: System send message to client
 */
function chatroom_livesupport_system_send_message($chatroom = ChatroomLivesupport, $system_message,$user = NULL) {
  // Notification Visitor
  $message = array(
    'uid' => $user->uid,
    'msg' => $system_message,
    'modified' => time()
  );

  $message += chatroom_livesupport_get_default_message($chatroom, $user);

  $cmid = $chatroom->saveMessage($message);

  $push_message = (object) array(
    'channel' => 'chatroom_' . $chatroom->get('cid'),
    'callback' => 'chatroomMessageHandler',
    'data' => array(
      'cid' => $chatroom->get('cid'),
      'cmid' => $cmid,
      'uid' => $user->uid,
      'timestamp' => $message['modified'],
      'msg' => theme('chatroom_message', array('message' => (object) $message, 'chatroom' => $chatroom)),
    ),
  );
  nodejs_send_content_channel_message($push_message);
}
/**
 * Update visitors page
 */
function chatroom_livesupport_nodejs_update_visitors() {
  global $user;  
  $push_message = (object) array(
    'channel' => 'chatroom_livesupport_visitor',
    'callback' => 'updateVisitorHandler',
    'data' => array(
      'uid' => $user->uid
    ),
  );
  Nodejs::enqueueMessage($push_message);
}
// Update chatroom
function chatroom_livesupport_nodejs_update_chatroom($chatroom = ChatroomLivesupport) {
  global $user;
  nodejs_send_content_channel_token('chatroom_' . $chatroom->get('cid'), TRUE);
  $push_message = (object) array(
    'channel' => 'chatroom_' . $chatroom->get('cid'),
    'callback' => 'updateChatroomHandler',
    'data' => array(
      'cid' => $chatroom->get('cid'),
      'uid' => $user->uid,
      'status' => $chatroom->get('status'),
    ),
  );
  nodejs_send_content_channel_message($push_message);
}